#include <iostream>
#include <functional>
using namespace std;

// function包装器
// template<class F, class T>
// T useF(F f, T x)
// {
// 	static int count = 0;
// 	cout << "count:" << ++count << endl;
// 	cout << "count:" << &count << endl;
// 	return f(x);
// }
// double f(double i)
// {
// 	return i / 2;
// }
// struct Functor
// {
// 	double operator()(double d)
// 	{
// 		return d / 3;
// 	}
// };
// int main()
// {
//     // 函数名
//     std::function<double(double)> func1 = f;
// 	cout << useF(func1, 11.11) << endl;
// 	// 函数对象
//     std::function<double(double)> func2 = Functor();
// 	cout << useF(func2, 11.11) << endl;
// 	// lamber表达式
//     std::function<double(double)> func3 = [](double d)->double{ return d/4; };
// 	cout << useF(func3, 11.11) << endl;
// 	return 0;
// }

// 使用方法如下：
// #include <functional>
// int f(int a, int b)
// {
// 	return a + b;
// }

// struct Functor
// {
// public:
// 	int operator() (int a, int b)
// 	{
// 		return a + b;
// 	}
// };

// class Plus
// {
// public:
//     Plus()
//     {
//         cout << "Plus()" << endl;
//     }
//     Plus(const Plus& plus)
//     {
//         cout << "Plus(const Plus& plus)" << endl;
//     }
// 	Plus(Plus&& plus)
//     {
//         cout << "Plus(Plus&& plus)" << endl;
//     }
// 	static int plusi(int a, int b)
// 	{
// 		return a + b;
// 	}
// 	double plusd(double a, double b)
// 	{
// 		return a + b;
// 	}
// };

// int main()
// {
// 	// 函数名(函数指针)
// 	std::function<int(int, int)> func1 = f;
// 	cout << func1(1, 2) << endl;
// 	// 函数对象
// 	std::function<int(int, int)> func2 = Functor(); //包装函数对象要加括号()
// 	cout << func2(1, 2) << endl;
// 	// lambda表达式
// 	std::function<int(int, int)> func3 = [](const int a, const int b){return a + b;};
// 	cout << func3(1, 2) << endl;
// 	// 静态成员函数
// 	std::function<int(int, int)> func4 = Plus::plusi; //包装静态成员函数可以不加&
// 	cout << func4(1, 2) << endl;
//     // 非静态成员函数
// 	std::function<double(Plus, double, double)> func5 = &Plus::plusd; //包装非静态成员函数必须加&
// 	cout << func5(Plus(), 1.1, 2.2) << endl;
//     Plus pl;
// 	cout << func5(pl, 2.2, 3.3) << endl;
// 	return 0;
// }

#include <functional>

int Sub(int a, int b)
{
	return a - b;
}

class Plus
{
public:
	Plus(int rate = 1)
		: _rate(rate)
	{
	}

	int plus(int a, int b)
	{
		return (a + b) * _rate;
	}

private:
	int _rate;
};

int main()
{
	// 调整参数顺序
	// 用function包装器直接包装函数Sub
	std::function<int(int, int)> func1 = Sub;
	cout << "func1(1, 2) -> " << func1(1, 2) << endl;
	// 绑定函数Sub，参数分别由func2的第2、第1参数指定
	// std::function<int(int, int)> func2 = std::bind(Sub, placeholders::_2, placeholders::_1);
	auto func2 = std::bind(Sub, placeholders::_2, placeholders::_1); // 可以使用auto自动推导类型
	cout << "func2(1, 2) -> " << func2(1, 2) << endl;

	// 调整参数个数
	// 用function包装器直接包装成员函数Plus::plus，第一个参数必须传调用对象
	std::function<int(Plus, int, int)> func3 = &Plus::plus;
	cout << "func3(Plus(3), 1, 2) -> " << func3(Plus(3), 1, 2) << endl;
	// 用bind绑定成员函数Plus::plus，将第一个参数固定为匿名对象Plus(3)。
	std::function<int(int, int)> func4 = std::bind(&Plus::plus, Plus(3), placeholders::_1, placeholders::_2);
	cout << "func4(1, 2) -> " << func4(1, 2) << endl;
	// 用bind绑定成员函数Plus::plus，将第二个参数固定为1。
	std::function<int(Plus, int)> func5 = std::bind(&Plus::plus, placeholders::_1, 1, placeholders::_2);
	cout << "func5(Plus(3), 2) -> " << func5(Plus(3), 2) << endl;
	return 0;
}